package com.sicheng.metadata.juc.cas;

import org.junit.Test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

public class CAS {
    private static final AtomicInteger atomic = new AtomicInteger(0);
    private static final AtomicStampedReference<Integer> reference =
            new AtomicStampedReference<>(1, 1);

    public static void main(String[] args) {
        atomic.compareAndSet(0, 1);
        System.out.println(atomic.getAndIncrement());


        ThreadLocal<Object> local = new ThreadLocal<>();
    }
    @Test
    public void testABA(){
        new Thread(()->{
            // 获得版本号
            int stamp = reference.getStamp();
            System.out.println("a1=>"+stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            reference.compareAndSet(
                    2020,
                    2022,
                    reference.getStamp(), // 最新版本号
                    // 更新版本号
                    reference.getStamp() + 1);
            System.out.println("a2=>"
                    +reference.getStamp());
            System.out.println(
                    reference.compareAndSet(
                            2022,
                            2020,
                            reference.getStamp(),
                            reference.getStamp() + 1));
            System.out.println("a3=>"
                    +reference.getStamp());
        },"a").start();
        // 乐观锁的原理相同！
        new Thread(()->{
            // 获得版本号
            int stamp = reference.getStamp();
            System.out.println("b1=>"+stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(
                    reference.compareAndSet(
                            2020, 6666, stamp, stamp + 1));
            System.out.println("b2=>"
                    +reference.getStamp());
        },"b").start();
    }
}
